"""
CRUD 操作

数据库的增删改查操作
"""

from sqlalchemy.orm import Session
from typing import Optional, List, Tuple
from pathlib import Path
import sys

# 处理导入路径
if __name__ == "__main__" or "." not in __name__:
    sys.path.insert(0, str(Path(__file__).parent.parent.parent))
    from stage2_advanced.chapter03_file_upload import models, schemas
else:
    from . import models, schemas


# ========== 文件查询操作 ==========

def get_file(db: Session, file_id: int) -> Optional[models.UploadedFile]:
    """
    根据 ID 获取文件
    
    Args:
        db: 数据库会话
        file_id: 文件 ID
        
    Returns:
        文件对象
    """
    return db.query(models.UploadedFile).filter(models.UploadedFile.id == file_id).first()


def get_file_by_stored_filename(db: Session, stored_filename: str) -> Optional[models.UploadedFile]:
    """
    根据存储文件名获取文件
    
    Args:
        db: 数据库会话
        stored_filename: 存储文件名
        
    Returns:
        文件对象
    """
    return db.query(models.UploadedFile).filter(
        models.UploadedFile.stored_filename == stored_filename
    ).first()


def get_files(
    db: Session,
    skip: int = 0,
    limit: int = 100,
    file_type: Optional[str] = None,
    uploader_id: Optional[int] = None,
    is_public: Optional[bool] = None
) -> List[models.UploadedFile]:
    """
    获取文件列表
    
    Args:
        db: 数据库会话
        skip: 跳过的记录数
        limit: 返回的最大记录数
        file_type: 文件类型过滤
        uploader_id: 上传者 ID 过滤
        is_public: 是否公开过滤
        
    Returns:
        文件对象列表
    """
    query = db.query(models.UploadedFile)
    
    # 应用过滤条件
    if file_type:
        query = query.filter(models.UploadedFile.file_type == file_type)
    if uploader_id is not None:
        query = query.filter(models.UploadedFile.uploader_id == uploader_id)
    if is_public is not None:
        query = query.filter(models.UploadedFile.is_public == is_public)
    
    # 按上传时间倒序
    query = query.order_by(models.UploadedFile.created_at.desc())
    
    return query.offset(skip).limit(limit).all()


def count_files(
    db: Session,
    file_type: Optional[str] = None,
    uploader_id: Optional[int] = None,
    is_public: Optional[bool] = None
) -> int:
    """
    统计文件数量
    
    Args:
        db: 数据库会话
        file_type: 文件类型过滤
        uploader_id: 上传者 ID 过滤
        is_public: 是否公开过滤
        
    Returns:
        文件数量
    """
    query = db.query(models.UploadedFile)
    
    if file_type:
        query = query.filter(models.UploadedFile.file_type == file_type)
    if uploader_id is not None:
        query = query.filter(models.UploadedFile.uploader_id == uploader_id)
    if is_public is not None:
        query = query.filter(models.UploadedFile.is_public == is_public)
    
    return query.count()


# ========== 文件创建操作 ==========

def create_file(
    db: Session,
    filename: str,
    stored_filename: str,
    file_path: str,
    file_type: str,
    file_size: int,
    mime_type: Optional[str] = None,
    file_hash: Optional[str] = None,
    width: Optional[int] = None,
    height: Optional[int] = None,
    uploader_id: Optional[int] = None,
    uploader_ip: Optional[str] = None,
    description: Optional[str] = None,
    tags: Optional[str] = None,
    is_public: bool = False
) -> models.UploadedFile:
    """
    创建文件记录
    
    Args:
        db: 数据库会话
        filename: 原始文件名
        stored_filename: 存储文件名
        file_path: 文件路径
        file_type: 文件类型
        file_size: 文件大小
        mime_type: MIME 类型
        file_hash: 文件哈希值
        width: 图片宽度
        height: 图片高度
        uploader_id: 上传者 ID
        uploader_ip: 上传者 IP
        description: 文件描述
        tags: 标签
        is_public: 是否公开
        
    Returns:
        创建的文件对象
    """
    db_file = models.UploadedFile(
        filename=filename,
        stored_filename=stored_filename,
        file_path=file_path,
        file_type=file_type,
        file_size=file_size,
        mime_type=mime_type,
        file_hash=file_hash,
        width=width,
        height=height,
        status=models.FileStatus.COMPLETED,
        uploader_id=uploader_id,
        uploader_ip=uploader_ip,
        description=description,
        tags=tags,
        is_public=is_public
    )
    
    db.add(db_file)
    db.commit()
    db.refresh(db_file)
    
    return db_file


# ========== 文件更新操作 ==========

def update_file(
    db: Session,
    file: models.UploadedFile,
    file_update: schemas.FileUpdate
) -> models.UploadedFile:
    """
    更新文件信息
    
    Args:
        db: 数据库会话
        file: 要更新的文件对象
        file_update: 更新数据
        
    Returns:
        更新后的文件对象
    """
    update_data = file_update.model_dump(exclude_unset=True)
    
    for field, value in update_data.items():
        setattr(file, field, value)
    
    db.commit()
    db.refresh(file)
    
    return file


def update_file_status(
    db: Session,
    file: models.UploadedFile,
    status: str
) -> models.UploadedFile:
    """
    更新文件状态
    
    Args:
        db: 数据库会话
        file: 文件对象
        status: 新状态
        
    Returns:
        更新后的文件对象
    """
    file.status = status
    db.commit()
    db.refresh(file)
    
    return file


# ========== 文件删除操作 ==========

def delete_file(db: Session, file_id: int) -> bool:
    """
    删除文件记录
    
    Args:
        db: 数据库会话
        file_id: 文件 ID
        
    Returns:
        是否删除成功
    """
    file = get_file(db, file_id=file_id)
    if file:
        db.delete(file)
        db.commit()
        return True
    return False


# ========== 缩略图操作 ==========

def create_thumbnail(
    db: Session,
    file_id: int,
    size_name: str,
    filename: str,
    file_path: str,
    width: int,
    height: int,
    file_size: int
) -> models.FileThumbnail:
    """
    创建缩略图记录
    
    Args:
        db: 数据库会话
        file_id: 原文件 ID
        size_name: 尺寸名称
        filename: 缩略图文件名
        file_path: 缩略图路径
        width: 宽度
        height: 高度
        file_size: 文件大小
        
    Returns:
        创建的缩略图对象
    """
    db_thumbnail = models.FileThumbnail(
        file_id=file_id,
        size_name=size_name,
        filename=filename,
        file_path=file_path,
        width=width,
        height=height,
        file_size=file_size
    )
    
    db.add(db_thumbnail)
    db.commit()
    db.refresh(db_thumbnail)
    
    return db_thumbnail


def get_thumbnails(db: Session, file_id: int) -> List[models.FileThumbnail]:
    """
    获取文件的所有缩略图
    
    Args:
        db: 数据库会话
        file_id: 文件 ID
        
    Returns:
        缩略图列表
    """
    return db.query(models.FileThumbnail).filter(
        models.FileThumbnail.file_id == file_id
    ).all()


# ========== 统计操作 ==========

def get_file_stats(db: Session, uploader_id: Optional[int] = None) -> dict:
    """
    获取文件统计信息
    
    Args:
        db: 数据库会话
        uploader_id: 上传者 ID（可选）
        
    Returns:
        统计信息字典
    """
    query = db.query(models.UploadedFile)
    
    if uploader_id is not None:
        query = query.filter(models.UploadedFile.uploader_id == uploader_id)
    
    files = query.all()
    
    # 总数和总大小
    total_files = len(files)
    total_size = sum(f.file_size for f in files)
    
    # 按类型统计
    by_type = {}
    for file_type in models.FileType:
        count = sum(1 for f in files if f.file_type == file_type)
        size = sum(f.file_size for f in files if f.file_type == file_type)
        by_type[file_type.value] = {"count": count, "size": size}
    
    # 按状态统计
    by_status = {}
    for status in models.FileStatus:
        count = sum(1 for f in files if f.status == status)
        by_status[status.value] = count
    
    return {
        "total_files": total_files,
        "total_size": total_size,
        "by_type": by_type,
        "by_status": by_status
    }

